package com.kvest.gpsservicetracker.service;

import android.app.AlarmManager;
import android.app.IntentService;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient;
import com.google.android.gms.location.LocationClient;
import com.google.android.gms.location.LocationRequest;
import com.kvest.gpsservicetracker.datamodel.DBLocationItem;
import com.kvest.gpsservicetracker.datastorage.GPSDatabase;
import com.kvest.gpsservicetracker.utils.LoggerService;

//TODO
//Сценарии теста
//1) Включать-отключать по сети определения
//2) Включать-отключать GPS
//3) Запустить при выключенном GPS и потом его врубить
//4) Тест чтобы таски отрабатывали
//5) Тест БД

public class GPSTrackerService extends IntentService {
    private static final String TAG = "GPS_SERVICE_TAG";
    private static final String ACTION_LOCATION = "com.kvest.ACTION_LOCATION";
    private static final String ACTION_WORKER1 = "com.kvest.ACTION_WORKER1";
    private static final int WORKER1_INTERVAL = 60000;
    private static final String ACTION_WORKER2 = "com.kvest.ACTION_WORKER2";
    private static final int WORKER2_INTERVAL = 80000;
    private static final int DEFAULT_INTERVAL = 10000;

    private static int interval = DEFAULT_INTERVAL;

    public GPSTrackerService() {
        super("Location service");
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "create GPSTrackerService");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "destroy GPSTrackerService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        String action = intent.getAction();
        Log.d(TAG, "action=" + action);

        if (ACTION_LOCATION.equals(action)) {
            handleLocationIntent(intent);
        } else if (ACTION_WORKER1.equals(action)) {
            handleWorker1(intent);
        } else if (ACTION_WORKER2.equals(action)) {
            handleWorker2(intent);
        }
    }

    private void handleLocationIntent(Intent intent) {
        Location location = intent.getParcelableExtra(LocationClient.KEY_LOCATION_CHANGED);
        if (location != null) {
            //save location to DB
            DBLocationItem dbLocationItem = new DBLocationItem(location);
            GPSDatabase gpsDatabase = new GPSDatabase(getApplicationContext());
            gpsDatabase.add(dbLocationItem);

            //Log location
            LoggerService.getInstance().writeLog("location from service=" + dbLocationItem.toString());
        } else {
            LoggerService.getInstance().writeLog("location from service=null");
        }
    }

    private void handleWorker1(Intent intent) {
        LoggerService.getInstance().writeLog("This is worker 1 handler ");
    }

    private void handleWorker2(Intent intent) {
        LoggerService.getInstance().writeLog("This is worker 2 handler ");
    }

    public static PendingIntent getLocationPendingIntent(Context context) {
        Intent intent = new Intent(context, GPSTrackerService.class);
        intent.setAction(ACTION_LOCATION);
        return PendingIntent.getService(context, 0, intent, 0);
    }

    public static void startTracking(Context context) {
        StartConnectionCallbacksListener startConnectionCallbacksListener = new StartConnectionCallbacksListener(context);
        LocationClient locationClient = new LocationClient(context, startConnectionCallbacksListener,
            new GooglePlayServicesClient.OnConnectionFailedListener() {
                @Override
                public void onConnectionFailed(ConnectionResult connectionResult) {
                    LoggerService.getInstance().writeLog("startTracking->onConnectionFailed: " + connectionResult.getErrorCode());
                }
        });
        startConnectionCallbacksListener.setLocationClient(locationClient);
        locationClient.connect();
    }

    public static void stopTracking(Context context) {
        StopConnectionCallbacksListener stopConnectionCallbacksListener = new StopConnectionCallbacksListener(context);
        LocationClient locationClient = new LocationClient(context, stopConnectionCallbacksListener,
            new GooglePlayServicesClient.OnConnectionFailedListener() {
                @Override
                public void onConnectionFailed(ConnectionResult connectionResult) {
                    LoggerService.getInstance().writeLog("stopTracking->onConnectionFailed: " + connectionResult.getErrorCode());
                }
            });
        stopConnectionCallbacksListener.setLocationClient(locationClient);
        locationClient.connect();
    }

    public static int getInterval() {
        return interval;
    }

    public static void setInterval(int interval) {
        GPSTrackerService.interval = interval;
    }

    private static class StartConnectionCallbacksListener implements GooglePlayServicesClient.ConnectionCallbacks {
        private LocationClient locationClient;
        private Context context;

        public StartConnectionCallbacksListener(Context context) {
            this.locationClient = null;
            this.context = context;
        }

        @Override
        public void onConnected(Bundle bundle) {
            LoggerService.getInstance().writeLog("startTracking->onConnected");
            if (locationClient != null && locationClient.isConnected()) {
                LocationRequest locationRequest = LocationRequest.create();
                locationRequest.setInterval(interval);
                locationRequest.setFastestInterval(interval);
                locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

                locationClient.requestLocationUpdates(locationRequest, getLocationPendingIntent(context));

                locationClient.disconnect();
            }
        }

        @Override
        public void onDisconnected() {
            LoggerService.getInstance().writeLog("startTracking->onDisconnected");
        }

        public void setLocationClient(LocationClient locationClient) {
            this.locationClient = locationClient;
        }
    }

    private static class StopConnectionCallbacksListener implements GooglePlayServicesClient.ConnectionCallbacks {
        private LocationClient locationClient;
        private Context context;

        public StopConnectionCallbacksListener(Context context) {
            this.locationClient = null;
            this.context = context;
        }

        @Override
        public void onConnected(Bundle bundle) {
            LoggerService.getInstance().writeLog("stopTracking->onConnected");
            if (locationClient != null && locationClient.isConnected()) {
                locationClient.removeLocationUpdates(getLocationPendingIntent(context));

                locationClient.disconnect();
            }
        }

        @Override
        public void onDisconnected() {
            LoggerService.getInstance().writeLog("stopTracking->onDisconnected");
        }

        public void setLocationClient(LocationClient locationClient) {
            this.locationClient = locationClient;
        }
    }

    public static void startWorkers(Context context) {
        AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);

        //Start worker 1
        Intent intent = new Intent(context, GPSTrackerService.class);
        intent.setAction(ACTION_WORKER1);
        PendingIntent pi = PendingIntent.getService(context, 0, intent, 0);
        am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + WORKER1_INTERVAL, WORKER1_INTERVAL, pi);

        //Start worker 2
        intent = new Intent(context, GPSTrackerService.class);
        intent.setAction(ACTION_WORKER2);
        pi = PendingIntent.getService(context, 0, intent, 0);
        am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + WORKER2_INTERVAL, WORKER2_INTERVAL, pi);
    }

    public static void stopWorkers(Context context) {
        AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);

        //Stop worker 1
        Intent intent = new Intent(context, GPSTrackerService.class);
        intent.setAction(ACTION_WORKER1);
        PendingIntent pi = PendingIntent.getService(context, 0, intent, 0);
        am.cancel(pi);

        //Stop worker 2
        intent = new Intent(context, GPSTrackerService.class);
        intent.setAction(ACTION_WORKER2);
        pi = PendingIntent.getService(context, 0, intent, 0);
        am.cancel(pi);
    }
}
